Rails6.0 Webpacker+Vue用capistrano部署时可能遇到的坑

Rails6.0 添加了webpack的支持,从此要在rails上引用前端库、打包前端资源变得非常的简单,再也不用像之前rails5.0的时候手工添加JS代码到vendor目录了,而是直接通过yarn指令添加前端库。在第一次上手使用rails webpacker并部署到生产环境时还是遇到了不少的坑。

  1. 如果你的云服务器很小,是个1G1C的小机机,那很可能在前端编译的时候会爆掉而部署中断。

    这时你比较好的解决思路是,在部署的过程中,让编译这个步骤在本地电脑上执行,然后再把编译出来的包上传到服务器上。

    在Capistrano部署代码中,可以这样做:

    在config/deploy.rb 文件的最后,添加以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    set :log_level, :debug
    set :format_options, truncate: false
    Rake::Task["deploy:compile_assets"].clear
    namespace :deploy do
    desc 'Compile assets'
    task :compile_assets => [:set_rails_env] do
    invoke 'deploy:assets:precompile_local'
    end
    namespace :assets do
    desc "Precompile assets locally and then rsync to web servers"
    task :precompile_local do
    run_locally do
    execute "RAILS_ENV=#{fetch(:stage)} bundle exec rake assets:precompile"
    end
    # rsync to each server
    on roles(:web), in: :parallel do |server|
    run_locally do
    execute :rsync,
    "-av --delete ./public/ #{'deploy'}@#{server.hostname}:#{release_path}/public/"
    end
    end
    run_locally do
    execute :rm, '-rf public/assets'
    execute :rm, '-rf public/packs'
    # execute :rm, 'public/index.html'
    end
    end
    end
    end

    这段代码主要做的是,先取消默认的编译步骤,再手工新建一个在本地电脑编译任务,任务完成后,再同步到生产服务器。

  2. 部署时可能会遇到报错Undefind async await

    这里是node版本的问题,云服务器上的node版本过低无法正常处理async await 等新特性。

    这里之所以是一个大坑是因为,很多时候在服务器上是通过nvm来控制node版本的

    • 默认版本已设为最新12.13.1
    • capistrano的deploy.rb部署配置通过capistrano-nvm设置node版本也为12.13.1

    但是重点来了,在部署的时候引用的却仍然是4.0的node版本,所以这个坑藏得有点深,我的做法是:把云服务器上的node和nvm全部完全卸载掉,通过手工编译安装新版的node,这才得以顺利部署。